/*
    Copyright 2010 Barnet Wagman

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
 */

package com.norbl.util.sdb;

import java.util.*;
import com.norbl.util.*;
import com.xerox.amazonws.sdb.*;

/** Handles access to a one sdb domain.  This class puts and gets sdb items.
 *  It does not provide access to individual attributes. <i>Note</i> that
 *  <tt>DomainWrangler</tt> assumes that each attribute in an item has no
 *  more than one value (even though sdb supports multiple values per
 *  attribute).
 *
 * @author Barnet Wagman
 */
abstract public class DomainWrangler {

    protected SdbOps dops;
    protected String domainName;

    public DomainWrangler(SdbOps dops, String domainName)
            throws SDBException {

        this.dops = dops;
        this.domainName = domainName;
        if (!dops.domainExist(domainName)) {
            dops.createDomain(domainName);
        }
    }

    /**
     *
     * @param pl
     * @param allowMissingFields if true, missing fields are set to
     *      <tt>null</tt>.
     * @return SDB item contents element.
     */
    abstract public DbEl toDbEl(PropertyList pl, boolean allowMissingFields);

    abstract public DbEl getTemplateDbEl();

    public void putItem(String itemName, DbEl el, boolean retry)
            throws SDBException {

        dops.putItem(domainName,
                itemName,
                el.toPropertyList(),
                retry);       
    }

    /** Gets all items in the domain.
     *
     * @return contents of the items in the domain.
     * @throws SDBException
     */
    public List<DbEl> getItems(boolean retry) throws SDBException {

        List<PropertyList> pls = dops.getItems(domainName, retry);

        List<DbEl> els = new ArrayList<DbEl>();

        for (PropertyList pl : pls) {
            els.add(toDbEl(pl, true));
        }

        return (els);
    }

    /**
     *
     * @param query 'select' string per sdb e.g.
     *  <tt>select * from some_domain_name where some_attribute = 'abc'</tt>
     * @return contents of the items in the domain that match the query.
     * @throws SDBException
     */
    public List<DbEl> getItems(String query, boolean retry) throws SDBException {

        List<PropertyList> pls = dops.getItems(domainName, query, retry);

        List<DbEl> els = new ArrayList<DbEl>();

        for (PropertyList pl : pls) {
            els.add(toDbEl(pl, true));
        }
        return (els);
    }

    public void deleteItem(String itemName, boolean retry) throws SDBException {
        dops.deleteItem(domainName, itemName, retry);
    }

        /** This method makes repeated {@link SdbOps#deleteItem(java.lang.String, java.lang.String, boolean)}
         *  calls until the domain is empty.
         *
         * @param retry
         * @throws SDBException
         */
    public void deleteAllItems(boolean retry) throws SDBException {
        dops.deleteItems(domainName,
                "select * from " + domainName,
                retry);
    }
}
